package com.douqu.game.main.msg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bean.core.buffer.ByteBuffer;
import com.bean.core.util.HttpStringUtil;
import com.bean.core.util.TimeUtils;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.*;
import com.douqu.game.core.config.card.CardConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.goods.PropConfig;
import com.douqu.game.core.config.map.CityConfig;
import com.douqu.game.core.config.sprite.SoldierConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.GMModel;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.e.*;
import com.douqu.game.core.entity.GameObject;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.BattleTemp;
import com.douqu.game.core.entity.battle.PlayerBattleData;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.*;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.entity.ext.SettingInfo;
import com.douqu.game.core.entity.ext.TaskInfo;
import com.douqu.game.core.entity.ext.data.challenge.CampBattleBean;
import com.douqu.game.core.entity.ext.data.challenge.CampBattleData;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapKillBean;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapTaskData;
import com.douqu.game.core.entity.ext.data.major.TalentBean;
import com.douqu.game.core.entity.ext.data.timeLimit.TimePropDB;
import com.douqu.game.core.entity.world.WorldArenaBean;
import com.douqu.game.core.entity.world.WorldArenaData;
import com.douqu.game.core.entity.world.WorldRankBean;
import com.douqu.game.core.entity.world.map.CityBean;
import com.douqu.game.core.entity.world.map.SpritePlayerBean;
import com.douqu.game.core.entity.world.map.WorldMapData;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.util.*;
import com.douqu.game.core.yjsdk.utils.MD5;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.server.ActivityCampManager;
import com.douqu.game.main.server.ServerManager;
import com.douqu.game.main.server.SpringContext;
import com.douqu.game.main.server.WorldManager;
import com.douqu.game.main.server.entity.MailSingle;
import com.douqu.game.main.server.entity.RankPlayerDetail;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.util.MsgUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-10-18 10:55
 */
public class GMPlayerChannel {

    public static void messageChannel(int code, NettyConnection connection, ByteBuffer data) throws Exception
    {
        switch (code)
        {
            case CodeFactory.GM_PLAYER_BASE_INFO:
                playerBaseInfo(connection, data);
                break;
            case CodeFactory.GM_PLAYER_EXT_INFO:
                playerExtInfo(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_OPTION:
                playerOption(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_ONLINE:
                playerOnline(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_ALL:
                playerAll(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_MAIL_SEND:
                sendMail(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_MAIL_REMOVE:
                removeMail(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_RECHARGE:
                recharge(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_CLEAR:
                playerClear(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_RANK:
                rankList(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_EXPORT:
                exportAllPlayer(connection, data, code);
                break;
            case CodeFactory.GM_PLAYER_TALENT_LIST:
                playerTalentInfo(connection, data, code);
                break;
        }
    }

    private static void playerTalentInfo(NettyConnection connection, ByteBuffer data, int code) {
        String playerIndex = data.readUTF();

        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
                .getPlayerResult(playerIndex);
        Player player = playerResult.getFirst();
        if (player == null) {
            GMChannel.sendError(connection, "玩家不存在");
            return;
        }
        Map<Integer, List<TalentBean>> talentMap =player.getTalentData().getTalentLibraryMap();
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject;
        for (List<TalentBean> list :talentMap.values()){
            for (TalentBean bean:list){
                jsonObject = new JSONObject();
                jsonObject.put("id", bean.getTalentId());
                jsonObject.put("upLv", bean.getLevel());
                jsonObject.put("refineLv", bean.getRefineLevel());
                jsonArray.add(jsonObject);
            }
        }
        JSONObject response = new JSONObject();
        response.put("data", jsonArray.toJSONString());
        ByteBuffer out = new ByteBuffer();
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());


    }


    private static void recharge(NettyConnection connection, ByteBuffer data, int code)
    {
        String playerIndex = data.readUTF();
        int rechargeId = data.readInt();
        String couponId = data.readUTF();
        GMModel gmModel = (GMModel) connection.getObject();
        RechargeConfig rechargeConfig = DataFactory.getInstance().getGameObject(DataFactory.RECHARGE_KEY, rechargeId);
        if (rechargeConfig == null) {
            GMChannel.sendError(connection, "没有此充值配置");
            return;
        }

        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
                .getPlayerResult(playerIndex);
        Player player = playerResult.getFirst();
        if (player == null) {
            GMChannel.sendError(connection, "玩家不存在");
            return;
        }
//		PlayerController playerController = playerResult.getSecond();
//		if (playerController == null){
//			GMChannel.sendError(connection,"玩家不在线");
//			return;
//		}
        TimePropDB timeProp = null;
        if (!couponId.equals(ConstantFactory.PLACEHOLDER) && rechargeConfig.type == E_RechargeGoodsType.DIAMOND.getCode()) {
            timeProp = player.getBagInfo().getTimePropData().getTimeProp(couponId);
            if (timeProp == null) {
                LogUtils.error("优惠卷不存在:" + couponId);
                GMChannel.sendError(connection, "优惠券不存在");
                return;
            } else {
                if (!timeProp.isTimeIn()) {
                    LogUtils.error("优惠卷已过期" + couponId);
                    GMChannel.sendError(connection, "优惠卷已过期");
                    return;
                } else if (timeProp.isUse) {
                    LogUtils.error("优惠卷已被使用" + couponId);
                    GMChannel.sendError(connection, "优惠卷已被使用");
                    return;
                } else if (rechargeConfig.rmb * 10 < timeProp.getConfig().timePropData.type) {
                    LogUtils.error("充值钻石不够，不能使用优惠券");
                    GMChannel.sendError(connection, "充值钻石不够，不能使用优惠券");
                    return;
                }
            }
        }

        StringBuffer sbEnc = new StringBuffer();
        sbEnc.append("app=GM");
        sbEnc.append("&cbi=");
        String rechargeParam = PayUtils.createRechargeParam(player.getObjectIndex(), rechargeId, GameServer.getInstance().getServerId(), player.getLv(), rechargeConfig.getDiamond(), playerResult.getSecond() != null ? playerResult.getSecond().getServerRuleId() : 0, timeProp, null, PayUtils.createOutTradeNo("GM"));
        sbEnc.append(rechargeParam);

        String time = TimeUtils.getCurrentTime(TimeUtils.YYYYMMDDHHMMSS + "SSS");
        sbEnc.append("&ct=");
        sbEnc.append(time);
        sbEnc.append("&fee=");
        sbEnc.append(rechargeConfig.rmb * 100);
        sbEnc.append("&pt=GM");
        sbEnc.append("&sdk=GM_");
        sbEnc.append(gmModel.getUsername());
        sbEnc.append("&ssid=");
        sbEnc.append(time);
        sbEnc.append("&st=1");
        sbEnc.append("&tcd=");
        sbEnc.append(time);
        sbEnc.append("&uid=");
        sbEnc.append(player.getObjectIndex());
        sbEnc.append("&ver=GM");
        String localSign = MD5.encode(sbEnc + PlatformFactory.YJ_PRIVATE_KEY);
        sbEnc.append("&sign=");
        sbEnc.append(localSign);
        LogUtils.info("本地秘钥：" + localSign);

        String result = HttpStringUtil.sendHttpPost(GameServer.getInstance().getAuthServerHost() + HttpFactory.PAY_YJ_CHECK + "?" + sbEnc.toString());
        LogUtils.info("冲值返回 -> " + result);
        ByteBuffer buffer = new ByteBuffer();
        buffer.writeUTF(result);

        connection.sendMsg(code, buffer.getBytes());
    }

    private static void sendMail(NettyConnection connection, ByteBuffer data, int code) {
        String objectIndex = data.readUTF();
        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
                .getPlayerResult(objectIndex);
        if (playerResult.getFirst() == null) {
            GMChannel.sendError(connection, "玩家不存在");
            return;
        }

        MailSingle mail = JSON.parseObject(data.readUTF(), MailSingle.class);
        if (!mail.check()) {
            GMChannel.sendError(connection, "参数错误");
            return;
        }

        MailDB mailDB = new MailDB();
        String title = mail.getTitle();
        String content = mail.getContent();
        mailDB.title = title;
        mailDB.content = content;
        mailDB.roleType = SGCommonProto.E_MAIL_SENDER_TYPE.MAIL_SENDER_TYPE_RECEIVER_VALUE;
        mailDB.sendTime = DataFactory.currentTime;
        mailDB.target = "-1";
        List<GoodsData> attachList = new CopyOnWriteArrayList<>();
        for (GoodsData goodsData : mail.getAttachArray()) {
            if (!goodsData.checkGoods()) {
                GMChannel.sendError(connection, "附件参数错误 -> id:" + goodsData.id + " count:" + goodsData.value);
                return;
            }
            attachList.add(goodsData);
        }
        mailDB.setAttachList(attachList);

        MailInfo mailInfo = playerResult.getFirst().getExtInfo(MailInfo.class);
        mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE, mailDB);

        if (playerResult.getSecond() == null)// 离线
        {
            GMChannel.savePlayer(playerResult.getFirst(), false, MailInfo.class);
        } else {
            // 在线,要推送新邮件消息
            SendUtils.mailPush(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM, playerResult.getSecond());
        }

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(getMailJson(mailDB).toJSONString());
        connection.sendMsg(code, out.getBytes());

        GMChannel.saveGMLog(connection, playerResult.getFirst(), "发送邮件:" + title, code, "mail");
    }

    private static String getMailListStr(MailInfo mailInfo) {
        List<MailDB> list = mailInfo.getMailList();
        JSONArray jsonArray = new JSONArray();
        for (int i = list.size() - 1; i >= 0; i--) {
            jsonArray.add(getMailJson(list.get(i)));
        }

        return jsonArray.toJSONString();
    }

    private static JSONObject getMailJson(MailDB mail) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", mail.id);
        jsonObject.put("title", mail.title);
        jsonObject.put("content", mail.content);
        jsonObject.put("roleType", mail.roleType);
        jsonObject.put("target", mail.target);
        jsonObject.put("sendTime", mail.sendTime);
        jsonObject.put("isGet", mail.isGet);
        jsonObject.put("isRead", mail.isRead);

        StringBuilder attachStr = new StringBuilder();
        for (GoodsData goodsData : mail.getAttachList()) {
            attachStr.append(goodsData.getGoodsStr());
            attachStr.append(",");
        }

        jsonObject.put("attachList", attachStr.length() > 0 ? attachStr.substring(0, attachStr.length() - 1) : "");

        return jsonObject;
    }

    private static void removeMail(NettyConnection connection, ByteBuffer data, int code) {

    }

    private static void playerAll(NettyConnection connection, ByteBuffer data, int code) {
        PlayerService playerService = SpringContext.getBean(PlayerService.class);
        int page = data.readShort();
        int count = data.readByte();
        page = page < 1 ? 1 : page;
        count = count < 1 ? 1 : count;

        String searchStr = data.available() > 0 ? data.readUTF() : "";
        String keyword = "";
        JSONObject searchJson = null;
        if (searchStr.length() > 0) {
            searchJson = JSONObject.parseObject(searchStr);
            keyword = searchJson.getString("keyword");
        }

        int totalCount = playerService.getAllPlayerCount(keyword);
        JSONObject response = new JSONObject();
        if (totalCount > 0) {
            List<PlayerModel> playerList = playerService.getPlayerList(page, count, keyword);
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = null;
            WorldManager worldManager = GameServer.getInstance().getWorldManager();
            for (PlayerModel player : playerList) {
                jsonObject = new JSONObject();
                jsonObject.put("channel", getChannel(player));
                jsonObject.put("objectIndex", player.getObjectIndex());
                jsonObject.put("uid", player.getUid());
                jsonObject.put("name", player.getName());
                jsonObject.put("camp", player.getCamp());
                jsonObject.put("lv", player.getLevel());
                jsonObject.put("fc", player.getFc());
                jsonObject.put("money", player.getMoney());
                jsonObject.put("online", worldManager.getPlayerControllerByUid(player.getUid()) != null);
                jsonObject.put("isDel", player.getIsDel());
                jsonObject.put("createTime", player.getCreateTime().getTime());
                jsonArray.add(jsonObject);
            }

            response.put("data", jsonArray.toJSONString());
        }

        response.put("page", page);
        response.put("count", count);
        response.put("totalCount", totalCount);
        response.put("search", searchJson);

        ByteBuffer out = new ByteBuffer(Integer.MAX_VALUE / 10);
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());
    }

    private static void playerOnline(NettyConnection connection, ByteBuffer data, int code) {
        int page = data.readShort();
        int count = data.readByte();
        page = page < 1 ? 1 : page;
        count = count < 1 ? 1 : count;

        String searchStr = data.available() > 0 ? data.readUTF() : "";
        String keyword = "";
        JSONObject searchJson = null;
        if (searchStr.length() > 0) {
            searchJson = JSONObject.parseObject(searchStr);
            keyword = searchJson.getString("keyword");
        }

        List<PlayerController> onlinePlayers = GameServer.getInstance().getWorldManager().getPlayerList();
        List<PlayerController> tempList = new CopyOnWriteArrayList<>();
        for (PlayerController player : onlinePlayers) {
            if (!StringUtils.isNullOrEmpty(keyword) && player.getName().indexOf(keyword) == -1)
                continue;

            tempList.add(player);
        }

        int start = (page - 1) * count;
        int end = start + count > tempList.size() ? tempList.size() : start + count;

        JSONObject response = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        if (start < tempList.size()) {
            PlayerController player = null;
            for (int i = start; i < end; i++) {
                player = tempList.get(i);
                jsonObject = new JSONObject();
                jsonObject.put("channel", getChannel(player));
                jsonObject.put("objectIndex", player.getObjectIndex());
                jsonObject.put("name", player.getName());
                jsonObject.put("camp", player.getPlayer().camp);
                jsonObject.put("lv", player.getPlayer().getLv());
                jsonObject.put("fc", player.getPlayer().fc);
                jsonObject.put("vipLv", player.getPlayer().getVipLevel());
                jsonObject.put("money", player.getPlayer().money);
                jsonObject.put("ip", player.getIp());
                jsonObject.put("invincible", player.getPlayer().invincible);
                jsonObject.put("loginTime", player.getPlayer().getLastLoginTime().getTime());
                jsonObject.put("status", player.getStatus().getMsg());
                jsonObject.put("lastUpdate", player.showLastUpdateInfo());
                jsonArray.add(jsonObject);
            }
            response.put("data", jsonArray.toJSONString());
        }

        response.put("page", page);
        response.put("count", count);
        response.put("totalCount", tempList.size());
        response.put("search", searchJson);

        ByteBuffer out = new ByteBuffer(Integer.MAX_VALUE / 10);
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());
    }

    private static void playerExtInfo(NettyConnection connection, ByteBuffer data, int code)
    {
        String type = data.readUTF();

        String playerIndex = data.readUTF();

        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager().getPlayerResult(playerIndex);
        Player player = playerResult.getFirst();
        if(player == null)
        {
            GMChannel.sendError(connection, "查询的玩家不存在");
            return;
        }

        JSONObject response = null;
        switch (type)
        {
            case CodeFactory.PLAYER_CARD_DETAIL:
                int cardId = data.readInt();
                CardDB cardDB = player.getCardData().getCard(cardId);
                if(cardDB == null)
                {
                    GMChannel.sendError(connection, "查询的卡牌不存在 -> " + cardId);
                    return;
                }
                response = playerCardDetail(player, cardDB);
                break;
            case CodeFactory.PLAYER_MAP_INFO:
                response = playerMapInfo(player);
                break;
            case CodeFactory.PLAYER_CAMP_INFO:
                response = playerCampInfo(player);
                break;
            case CodeFactory.PLAYER_TASK_INFO:
                response = playerTaskInfo(player);
                break;
            case CodeFactory.PLAYER_BOON_INFO:
                response = playerBoonInfo(player);
                break;
            case CodeFactory.PLAYER_CHALLENGE_INFO:
                response = playerChallengeInfo(player);
                break;
            case CodeFactory.PLAYER_IN_OUT_LOG:
                response = playerInOutLog(player);
                break;
        }

        if(response != null)
        {
            ByteBuffer out = new ByteBuffer();
            out.writeUTF(type);
            out.writeUTF(response.toJSONString());
            connection.sendMsg(code, out.getBytes());
        }
    }
    private static JSONObject playerInOutLog(Player player)
    {
        JSONObject response = new JSONObject();

        return response;
    }
    private static JSONObject playerChallengeInfo(Player player)
    {
        JSONObject response = new JSONObject();

        return response;
    }
    private static JSONObject playerBoonInfo(Player player)
    {
        JSONObject response = new JSONObject();

        return response;
    }

    private static JSONObject playerTaskInfo(Player player)
    {
        JSONObject response = new JSONObject();

        return response;
    }

    private static JSONObject playerCardDetail(Player player, CardDB cardDB)
    {
        JSONObject response = new JSONObject();

        response.put("id", cardDB.id);
        response.put("name", cardDB.getConfig().name);
        response.put("lv", cardDB.getLv());
        response.put("star", cardDB.star);
        response.put("fc", cardDB.fc);

        StringBuilder temp = new StringBuilder();
        GameObject gameObject = null;
        for (Integer fateId : cardDB.getActiveFateList()) {
            gameObject = DataFactory.getInstance().getGameObject(DataFactory.CARD_FATE_KEY, fateId);
            temp.append(gameObject.name);
            temp.append(",");
        }
        response.put("fate", temp.length() > 0 ? temp.substring(0, temp.length() - 1) : "");

        Map<String, Integer> map = new TreeMap<>();

        JSONArray jsonArray = new JSONArray();

        SoldierConfig soldierConfig = cardDB.getConfig().getSoldier();
        String hpGrow = soldierConfig.getVariable("hpGrow");
        String atkGrow = soldierConfig.getVariable("atkGrow");
        String defGrow = soldierConfig.getVariable("defGrow");

        JSONObject jsonObject = new JSONObject();
        for(E_AttributePlusType type : E_AttributePlusType.values())
        {
            if(type == E_AttributePlusType.ALL)
                continue;

            jsonArray.add(getCardAttribute(cardDB, type, hpGrow, atkGrow, defGrow, jsonObject));
        }

        jsonArray.add(jsonObject);

        response.put("infoList", jsonArray);

        jsonArray = new JSONArray();
        for(EquipDB equipDB : cardDB.getEquipMap().values())
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", equipDB.id);
            jsonObject.put("name", equipDB.getConfig().name + " Lv" + equipDB.getLv());
            jsonObject.put(E_Attribute.HP.getMsg(), equipDB.getAttribute(E_Attribute.HP.getCode()));
            jsonObject.put(E_Attribute.HP_GROW.getMsg(), equipDB.getConfig().getVariable(E_Attribute.HP_GROW.getMsg()));
            jsonObject.put(E_Attribute.ATK.getMsg(), equipDB.getAttribute(E_Attribute.ATK.getCode()));
            jsonObject.put(E_Attribute.ATK_GROW.getMsg(), equipDB.getConfig().getVariable(E_Attribute.ATK_GROW.getMsg()));
            jsonObject.put(E_Attribute.DEF.getMsg(), equipDB.getAttribute(E_Attribute.DEF.getCode()));
            jsonObject.put(E_Attribute.DEF_GROW.getMsg(), equipDB.getConfig().getVariable(E_Attribute.DEF_GROW.getMsg()));
            jsonObject.put(E_Attribute.CRI.getMsg(), equipDB.getAttribute(E_Attribute.CRI.getCode()));
            jsonObject.put(E_Attribute.REC.getMsg(), equipDB.getAttribute(E_Attribute.REC.getCode()));
            jsonObject.put(E_Attribute.ADD.getMsg(), equipDB.getAttribute(E_Attribute.ADD.getCode()));
            jsonObject.put(E_Attribute.EXD.getMsg(), equipDB.getAttribute(E_Attribute.EXD.getCode()));
            jsonObject.put(E_Attribute.HIT.getMsg(), equipDB.getAttribute(E_Attribute.HIT.getCode()));
            jsonObject.put(E_Attribute.EVA.getMsg(), equipDB.getAttribute(E_Attribute.EVA.getCode()));
            jsonArray.add(jsonObject);
        }

        response.put("equipList", jsonArray);

        jsonArray = new JSONArray();
        for(AccessoryDB accessoryDB : cardDB.getAccessoryMap().values())
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", accessoryDB.id);
            jsonObject.put("name", accessoryDB.getConfig().name + (accessoryDB.isActivated ? (" Lv" + accessoryDB.getLv() + " " + accessoryDB.upLv + "阶") : "(未激活)"));
            if(accessoryDB.isActivated)
            {
                jsonObject.put(E_Attribute.HP.getMsg(), accessoryDB.getAttribute(E_Attribute.HP.getCode()));
                jsonObject.put(E_Attribute.HP_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.HP_GROW.getMsg()));
                jsonObject.put(E_Attribute.ATK.getMsg(), accessoryDB.getAttribute(E_Attribute.ATK.getCode()));
                jsonObject.put(E_Attribute.ATK_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.ATK_GROW.getMsg()));
                jsonObject.put(E_Attribute.DEF.getMsg(), accessoryDB.getAttribute(E_Attribute.DEF.getCode()));
                jsonObject.put(E_Attribute.DEF_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.DEF_GROW.getMsg()));
                jsonObject.put(E_Attribute.CRI.getMsg(), accessoryDB.getAttribute(E_Attribute.CRI.getCode()));
                jsonObject.put(E_Attribute.REC.getMsg(), accessoryDB.getAttribute(E_Attribute.REC.getCode()));
                jsonObject.put(E_Attribute.ADD.getMsg(), accessoryDB.getAttribute(E_Attribute.ADD.getCode()));
                jsonObject.put(E_Attribute.EXD.getMsg(), accessoryDB.getAttribute(E_Attribute.EXD.getCode()));
                jsonObject.put(E_Attribute.HIT.getMsg(), accessoryDB.getAttribute(E_Attribute.HIT.getCode()));
                jsonObject.put(E_Attribute.EVA.getMsg(), accessoryDB.getAttribute(E_Attribute.EVA.getCode()));
            }
            else
            {
                jsonObject.put(E_Attribute.HP.getMsg(), 0);
                jsonObject.put(E_Attribute.HP_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.HP_GROW.getMsg()));
                jsonObject.put(E_Attribute.ATK.getMsg(), 0);
                jsonObject.put(E_Attribute.ATK_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.ATK_GROW.getMsg()));
                jsonObject.put(E_Attribute.DEF.getMsg(), 0);
                jsonObject.put(E_Attribute.DEF_GROW.getMsg(), accessoryDB.getConfig().getVariable(E_Attribute.DEF_GROW.getMsg()));
                jsonObject.put(E_Attribute.CRI.getMsg(), 0);
                jsonObject.put(E_Attribute.REC.getMsg(), 0);
                jsonObject.put(E_Attribute.ADD.getMsg(), 0);
                jsonObject.put(E_Attribute.EXD.getMsg(), 0);
                jsonObject.put(E_Attribute.HIT.getMsg(), 0);
                jsonObject.put(E_Attribute.EVA.getMsg(), 0);
            }

            jsonArray.add(jsonObject);
        }

        response.put("accessoryList", jsonArray);

        return response;
    }




    private static JSONObject playerMapInfo(Player player)
    {
        WorldMapTaskData worldMapTaskData = player.getWorldMapTaskData();
        List<CardDB> cardList = player.getWorldMapCardList();

        JSONObject response = new JSONObject();

        response.put("playerName", player.name);
        response.put("maxMultiKill", worldMapTaskData.getKillData().getHistorySkillCount());
        response.put("curMultiKill", worldMapTaskData.getKillData().getSkillCount());
        WorldMapKillBean killBean = worldMapTaskData.getKillData().getKillBean(E_WorldMapKillRankType.CURRENT_WEEK_RANK);
        if(killBean != null)
        {
            response.put("curKillRank", GameServer.getInstance().getWorldManager().getRankByPlayer(player, SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPCURRWEEK));
            response.put("curKillScore", killBean.getMaxValue());
            response.put("curKillTotalScore", killBean.getTotalValue());
        }
        else
        {
            response.put("curKillRank", 0);
            response.put("curKillScore", 0);
            response.put("curKillTotalScore", 0);
        }

        killBean = worldMapTaskData.getKillData().getKillBean(E_WorldMapKillRankType.LAST_WEEK_RANK);
        if(killBean != null)
        {
            response.put("lastWeekKillRank", GameServer.getInstance().getWorldManager().getRankByPlayer(player, SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK));
            response.put("lastWeekKillScore", killBean.getMaxValue());
            response.put("lastWeekKillTotalScore", killBean.getTotalValue());
        }
        else
        {
            response.put("lastWeekKillRank", 0);
            response.put("lastWeekKillScore", 0);
            response.put("lastWeekKillTotalScore", 0);
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(player.getObjectIndex());
        SpritePlayerBean spritePlayerBean = worldMapData != null ? worldMapData.getPlayerActionBean(player.getObjectIndex()) : null;
        BattleTemp battleTemp = null;
        if(spritePlayerBean != null)
        {
            battleTemp = spritePlayerBean.getBattleTemp();
            response.put("masterHPRate", battleTemp.getMasterHPRate());
            response.put("armyHPRate", battleTemp.getArmyHPRate());
            CityConfig cityConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_KEY, spritePlayerBean.getCurCity());
            if(cityConfig != null)
                response.put("curCity", cityConfig!=null?cityConfig.name:"无");
            response.put("armyStatus", spritePlayerBean.getStatus().getNumber());
        }
        else
        {
            response.put("masterHPRate", 100);
            response.put("armyHPRate", 100);
            response.put("curCity", "无");
            response.put("armyStatus", "无");
        }

        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        for(CardDB cardDB : cardList)
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", cardDB.id);
            jsonObject.put("name", cardDB.getConfig().name + " Lv" + cardDB.getLv());
            jsonObject.put("fc", cardDB.fc);
            jsonObject.put("atk", cardDB.getAttribute(E_Attribute.ATK.getCode()));
            jsonObject.put("def", cardDB.getAttribute(E_Attribute.DEF.getCode()));
            jsonObject.put("cri", cardDB.getAttribute(E_Attribute.CRI.getCode()));
            jsonObject.put("rec", cardDB.getAttribute(E_Attribute.REC.getCode()));
            jsonObject.put("add", cardDB.getAttribute(E_Attribute.ADD.getCode()));
            jsonObject.put("exd", cardDB.getAttribute(E_Attribute.EXD.getCode()));
            jsonObject.put("hit", cardDB.getAttribute(E_Attribute.HIT.getCode()));
            jsonObject.put("eva", cardDB.getAttribute(E_Attribute.EVA.getCode()));
            if(battleTemp == null)
            {
                long hp = cardDB.getAttribute(E_Attribute.HP.getCode());
                jsonObject.put("hp", hp + "/" + hp);
            }
            else
            {
                jsonObject.put("hp", battleTemp.getHPStr(cardDB.id));
            }
            jsonArray.add(jsonObject);
        }
        response.put("cardList", jsonArray);

        return response;
    }

    private static JSONObject playerCampInfo(Player player)
    {
        JSONObject response = new JSONObject();
        CampBattleData campBattleData = player.getCampBattleData();
        //报名次数,复活次数,排名，累计功勋,连胜,战斗记录,胜率
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("activityIndex", campBattleData.activityIndex);
        jsonObject.put("applyCount", campBattleData.applyCount);
        jsonObject.put("reviveCount", campBattleData.reviveCount);
        jsonObject.put("isGetReward", campBattleData.isGetRewarded());

        jsonObject.put("maxRank", campBattleData.maxRank);
        int myRank = ActivityCampManager.getInstance().getMyRank(player.getObjectIndex());
        myRank = myRank < 0 ? 0 : myRank;
        jsonObject.put("rank", myRank);

        jsonObject.put("totalExploit", campBattleData.totalExploit);
        jsonObject.put("totalWinRate", campBattleData.getTotalWinRate());
        jsonObject.put("maxContinueWin", campBattleData.maxContinueWin);
        jsonObject.put("curMaxContinueWin", campBattleData.curMaxContinueWin);
        jsonObject.put("curTotalExploit", campBattleData.curTotalExploit);
        jsonObject.put("curWinRate", campBattleData.getCurWinRate());
//		jsonObject.put("curWinCount", campBattleData.curWinCount);
//		jsonObject.put("curBattleCount", campBattleData.curBattleCount);

        response.put("baseInfo", jsonObject);

        JSONArray jsonArray = new JSONArray();

        int index = 0;
        for(CampBattleBean campBattleBean : campBattleData.getBattleList())
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", ++index);
            jsonObject.put("win", campBattleBean.win);
            jsonObject.put("targetName", campBattleBean.targetName);
            jsonObject.put("targetFC", campBattleBean.targetFC);
            jsonObject.put("targetServerId", campBattleBean.targetServerId);
            campBattleBean.parseParam(jsonObject);
            jsonArray.add(jsonObject);
        }

        response.put("battleList", jsonArray);

        jsonArray = new JSONArray();
        BattleTemp battleTemp = GameServer.getInstance().getWorldManager().getSpriteBattleTemp(SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_SPAN_CAMP_VALUE, player.getObjectIndex());
        for(CardDB cardDB : player.getCampCardList())
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", cardDB.id);
            jsonObject.put("name", cardDB.getConfig().name + " Lv" + cardDB.getLv());
            jsonObject.put("fc", cardDB.fc);
            jsonObject.put("atk", cardDB.getAttribute(E_Attribute.ATK.getCode()));
            jsonObject.put("def", cardDB.getAttribute(E_Attribute.DEF.getCode()));
            jsonObject.put("cri", cardDB.getAttribute(E_Attribute.CRI.getCode()));
            jsonObject.put("rec", cardDB.getAttribute(E_Attribute.REC.getCode()));
            jsonObject.put("add", cardDB.getAttribute(E_Attribute.ADD.getCode()));
            jsonObject.put("exd", cardDB.getAttribute(E_Attribute.EXD.getCode()));
            jsonObject.put("hit", cardDB.getAttribute(E_Attribute.HIT.getCode()));
            jsonObject.put("eva", cardDB.getAttribute(E_Attribute.EVA.getCode()));
            if(battleTemp == null)
            {
                long hp = cardDB.getAttribute(E_Attribute.HP.getCode());
                jsonObject.put("hp", hp + "/" + hp);
            }
            else
            {
                jsonObject.put("hp", battleTemp.getHPStr(cardDB.id));
            }
            jsonArray.add(jsonObject);
        }
        response.put("cardList", jsonArray);
        return response;
    }

    private static void playerBaseInfo(NettyConnection connection, ByteBuffer data) {
        String queryType = data.readUTF();
        String queryValue = data.readUTF();
        PlayerController playerController = null;
        Player player = null;
        WorldManager worldManager = GameServer.getInstance().getWorldManager();
        switch (queryType) {
            case CodeFactory.QUERY_TYPE_NICK_NAME:
                playerController = worldManager.getPlayerControllerByName(queryValue);
                break;
            // case CodeFactory.QUERY_TYPE_UID:
            // playerController =
            // worldManager.getPlayerControllerByUid(Integer.parseInt(queryValue));
            // break;
            case CodeFactory.QUERY_TYPE_OBJECT_INDEX:
                playerController = worldManager.getPlayerController(queryValue);
                break;
        }

        if (playerController == null) {
            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            PlayerModel playerModel = null;
            switch (queryType) {
                case CodeFactory.QUERY_TYPE_NICK_NAME:
                    playerModel = playerService.getPlayerByName(queryValue);
                    break;
                // case CodeFactory.QUERY_TYPE_UID:
                // playerModel =
                // playerService.getPlayerByUid(Integer.parseInt(queryValue)).get(0);
                // break;
                case CodeFactory.QUERY_TYPE_OBJECT_INDEX:
                    playerModel = playerService.getPlayerByIndex(queryValue);
                    break;
            }
            if (playerModel != null) {
                player = new Player(playerModel);
            }
        } else {
            player = playerController.getPlayer();
        }

        if (player == null) {
            GMChannel.sendError(connection, "玩家不存在!");
            return;
        }

        sendPlayerBaseInfo(connection, player, playerController);
    }

    private static void sendPlayerBaseInfo(NettyConnection connection, Player player, PlayerController playerController) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("channel", getChannel(player));
        jsonObject.put("name", player.name);
        jsonObject.put("uid", player.getUid());
        jsonObject.put("account",
                player.getAccount() == null ? "" : player.getAccount().substring(player.getAccount().indexOf("_") + 1));
        jsonObject.put("objectIndex", player.objectIndex);
        jsonObject.put("fc", player.fc);
        jsonObject.put("lv", getLvData(player));
        jsonObject.put("vipLv", getVipLvData(player));
        jsonObject.put("camp", player.camp);
        jsonObject.put("online",
                GameServer.getInstance().getWorldManager().getPlayerControllerByUid(player.getUid()) != null);
        jsonObject.put("createTime", player.getCreateTime());
        jsonObject.put("loginTime", player.getLastLoginTime());
        jsonObject.put("isDel", player.isDel);

        jsonObject.put("assetInfo", getAssetStr(player));

        jsonObject.put("propInfo", getPropStr(player));

        jsonObject.put("cardInfo", getCardStr(player));

        MailInfo mailInfo = player.getExtInfo(MailInfo.class);
        jsonObject.put("mailInfo", getMailListStr(mailInfo));

        if (playerController != null) {
            if (playerController.getBattleData() != null) {
                PlayerBattleData battleData = playerController.getBattleData();
                JSONObject battleJson = new JSONObject();
                battleJson.put("serverId", battleData.getBattleServerPort());
                battleJson.put(CodeFactory.KEY_BATTLE_TYPE, battleData.getBattleType());
                battleJson.put(CodeFactory.KEY_BATTLE_ID, battleData.getBattleId());
                jsonObject.put("battleInfo", battleJson);
            }
        }

        ByteBuffer out = new ByteBuffer(Integer.MAX_VALUE / 10);
        out.writeUTF(jsonObject.toJSONString());
        connection.sendMsg(CodeFactory.GM_PLAYER_BASE_INFO, out.getBytes());
    }

    private static void playerOption(NettyConnection connection, ByteBuffer data, int code) {
        GMModel gmModel = (GMModel) connection.getObject();

        JSONObject request = JSON.parseObject(data.readUTF());
        String optionType = request.getString("optionType");
        String playerIndex = request.getString("playerIndex");

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(optionType);

        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
                .getPlayerResult(playerIndex);
        Player player = playerResult.getFirst();
        PlayerController playerController = playerResult.getSecond();
        if (player == null) {
            GMChannel.sendError(connection, "玩家不存在");
            return;
        }

        if (!GMChannel.isCanOption(gmModel, optionType)) {
            GMChannel.sendError(connection, "你没有权限操作此功能");
            return;
        }

        if (CodeFactory.GM_OPTION_OTHER.equals(optionType))
        {
            String cmdValue = request.getString("cmd");
            if (StringUtils.isNullOrEmpty(cmdValue)) {
                GMChannel.sendError(connection, "参数错误");
                return;
            }

            String[] strs = cmdValue.split(":");
            String cmd = strs[0];
            out.writeUTF(cmd);
            // 指令操作
            if ("reset".equals(cmd)) {
                if (!player.getHeroTempleData().isChallengeTimesEnough()) {
                    player.getHeroTempleData().reset();
                }

                if (!playerController.getPlayer().getArenaData().isChallengeTimesEnough()) {
                    player.getArenaData().reset();
                }

                if (!playerController.getPlayer().getOfficialData().isChallengeTimesEnough()) {
                    player.getOfficialData().reset();
                }
            } else if ("backMain".equals(cmd)) {
                WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData();
                SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerIndex);
                if (spritePlayerBean == null) {
                    GMChannel.sendError(connection, "请先进入大地图");
                    return;
                }

                CityBean cityBean = worldMapData.getCity(spritePlayerBean.getCurCity());
                if (cityBean == null) {
                    GMChannel.sendError(connection, "参数错误 -> " + spritePlayerBean.getCurCity());
                    return;
                }

                worldMapData.backMainCity(spritePlayerBean, SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_FREE, true);

                SendUtils.sendEnterWorldMap(spritePlayerBean, worldMapData);

                SendUtils.sendMapArmyStatus(playerController, spritePlayerBean.getStatus());

                playerController.sendWarn("GM把你传送到了 " + cityBean.getConfig().getName());
            } else if ("super".equals(cmd)) {
                BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
                List<CardConfig> cardConfigs = DataFactory.getInstance().getDataList(DataFactory.CARD_KEY);
                List<AssetConfig> assetConfigs = DataFactory.getInstance().getDataList(DataFactory.ASSET_KEY);
                List<PropConfig> propConfigs = DataFactory.getInstance().getDataList(DataFactory.PROP_KEY);

                List<GoodsData> goodsDataList = new ArrayList<>();
                for (CardConfig cardConfig : cardConfigs) {
                    goodsDataList
                            .add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_CARDS_VALUE, cardConfig.id, 10));
                }
                for (AssetConfig assetConfig : assetConfigs) {
                    goodsDataList.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, assetConfig.id,
                            10000000));
                }
                for (PropConfig propConfig : propConfigs) {
                    if (propConfig.type == ConstantFactory.PROP_TYPE_TIME_PROP)
                        continue;

                    goodsDataList.add(
                            new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE, propConfig.id, 10000000));
                }
                GoodsData[] goodsDatas = new GoodsData[goodsDataList.size()];
                for (int i = 0; i < goodsDataList.size(); i++) {
                    goodsDatas[i] = goodsDataList.get(i);
                }
                bagInfo.addGoods(goodsDatas, null);
            } else if (cmd.equals("addVipExp")) {
                int vipExp = Integer.parseInt(strs[1]);
                if (vipExp == 0){
                    GMChannel.sendError(connection, "参数错误 vipExp-> " + vipExp);
                    return;
                }

                player.addVipExp(vipExp);

                out.writeUTF(getVipLvData(player));
            } else if ("missionCompleted".equals(cmd)) {
                missionCompleted(connection, playerController);
            } else if (cmd.equals("applyCampBattle")) {
                if (CoreUtils.isNullOrEmpty(ActivityCampManager.getInstance().getIndex())) {
                    GMChannel.sendError(connection, "活动服务器没有开启");
                    return;
                }
                StableDataConfig stableData = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                        E_StableDataType.CAMP_ACTIVITY_APPLY.getCode());
                BagInfo bagInfo = player.getExtInfo(BagInfo.class);
                player.getCampBattleData().apply(ActivityCampManager.getInstance().getIndex(), stableData.intValue,
                        bagInfo.getCardData().getBattleCardList());

                ActivityCampManager.getInstance().applySuccess(playerController);

                ServerManager.getInstance().sendApplyActivity(playerController.getPlayer(), E_ApplyCampActivityType.GM);
            } else if (cmd.equals("clearCampBattle")) {
                player.getCampBattleData().clearApplyData();
                ActivityCampManager.getInstance().removePlayer(player.getObjectIndex());
                player.getCampBattleData().clearReward();
            } else if (cmd.equals("clearCampApplyData")) {
                player.getCampBattleData().clearApplyData();
                ActivityCampManager.getInstance().removePlayer(player.getObjectIndex());
            } else if (cmd.equals("clearCampRewardData")) {
                player.getCampBattleData().clearReward();
            } else if ("createBoss".equals(cmd)) {
//                int bossId = createBoss(connection);
//                if (bossId != 0) {
//                    GMChannel.saveGMLog(connection, player, "创建世界BOSS -> " + bossId, code, bossId + "");
//                }
            } else if("fly".equals(cmd)){
                WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData();
                SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerIndex);
                if (spritePlayerBean == null) {
                    GMChannel.sendError(connection, "请先进入大地图");
                    return;
                }

                if(!spritePlayerBean.isFree())
                {
                    GMChannel.sendError(connection, "玩家不为空闲");
                    return;
                }

                int cityId = 0;
                if(strs.length == 0 || strs[1].equals("0"))
                {
                    //随机飞
                    List<CityConfig> list = DataFactory.getInstance().getDataList(DataFactory.CITY_KEY);
                    cityId = list.get(Utils.getRandom(list.size())).id;
                }
                else
                {
                    cityId = Integer.parseInt(strs[1]);
                }
                LogUtils.info("飞到－> " + cityId);
                CityBean cityBean = worldMapData.getCity(cityId);
                if (cityBean == null) {
                    GMChannel.sendError(connection, "参数错误 -> " + cityId);
                    return;
                }

                cityBean.arrive(spritePlayerBean, true, E_CityInOutType.IN_GM);

                SendUtils.sendEnterWorldMap(spritePlayerBean, worldMapData);

                playerController.sendWarn("GM把你传送到了 -> " + cityBean.getConfig().name);
            } else{
                GoodsData goodsData = new GoodsData(cmd);
                BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
                bagInfo.addGoods(new GoodsData[] { goodsData }, null);
            }
        } else {
            if (optionType.equals(CodeFactory.GM_OPTION_INVINCIBLE))
            {
                if (playerController == null) {
                    GMChannel.sendError(connection, "不允许对离线玩家操作此功能");
                    return;
                }
                player.invincible = !player.invincible;

                if (player.invincible) {
                    playerResult.getSecond().sendWarn("你已被GM设置为无敌状态,赶快进入新一轮战斗体验吧!");
                } else {
                    playerResult.getSecond().sendWarn("你已被GM恢复为默认状态,将在新的战斗中生效!");
                }
                LogUtils.info("玩家:" + player.getName() + " 是否无敌:" + player.invincible);
                out.writeUTF(playerIndex);
                out.writeBoolean(player.invincible);
                GMChannel.saveGMLog(connection, player, "设置为" + (player.invincible ? "无敌" : "默认") + "状态", code,
                        player.invincible + "");
            }
            else if(optionType.equals(CodeFactory.GM_OPTION_OFFLINE))
            {
                if (playerController == null) {
                    GMChannel.sendError(connection, "玩家不在线");
                    return;
                }
                if(playerController.isBattling())
                {
                    GMChannel.sendError(connection, "玩家正在战斗中，请稍候再试");
                    return;
                }

                GameServer.getInstance().playerOffline(playerController, true, E_OffLineType.OFFLINE_GM);

                GMChannel.saveGMLog(connection, player, "T下线", code, "offlinePlayer");

                out.writeUTF(playerIndex);
            }
            else if(optionType.equals(CodeFactory.GM_OPTION_FORBID))
            {
                if(playerController != null && playerController.isBattling())
                {
                    //在线的玩家,在战斗中暂时不封号
                    GMChannel.sendError(connection, "玩家正在战斗中，请稍候再试");
                    return;
                }

                player.isDel = !player.isDel;

                if(playerController != null && player.isDel)
                {
                    playerController.sendWarn(WordFactory.LOCK_ACCOUNT);

                    ServerManager.getInstance().sendOffline(playerController);

                    playerController.sendOffline();

                    GameServer.getInstance().getWorldManager().playerExitGame(playerController, E_OffLineType.OFFLINE_OVERTIME);

                    GMChannel.savePlayer(playerController.getPlayer());
                }

                out.writeUTF(playerIndex);
                out.writeBoolean(player.isDel);
            }
            else
            {
                String idStr = request.getString("id");
                int id = StringUtils.isNullOrEmpty(idStr) ? 0 : Integer.parseInt(idStr);
                long longValue = request.getLong("count");
                if (longValue == 0 || longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
                    GMChannel.sendError(connection, "请输入有效的数量!");
                    return;
                }
                int count = (int) longValue;
                BagInfo bagInfo = player.getExtInfo(BagInfo.class);
                switch (optionType) {
                    case CodeFactory.GM_OPTION_ADD_PROP:
                        int addResult = bagInfo.addProp(id, count);
                        if (addResult != -1) {
                            out.writeUTF(getPropStr(player));
                            PropConfig prop = DataFactory.getInstance().getGameObject(DataFactory.PROP_KEY, id);
                            if (prop.type == ConstantFactory.PROP_TYPE_CARD_SYN)
                                out.writeUTF(getCardStr(player));
                            GMChannel.saveGMLog(connection, player, "添加道具:" + prop.getName() + "x" + count, code,
                                    optionType + ":" + id + ":" + count);
                        } else {
                            GMChannel.sendError(connection, "参数错误!");
                            return;
                        }
                        break;
                    case CodeFactory.GM_OPTION_ADD_ASSET:
                        boolean assetResult = bagInfo.addAsset(id, count);
                        if (assetResult) {
                            out.writeUTF(getAssetStr(player));
                            AssetConfig asset = DataFactory.getInstance().getGameObject(DataFactory.ASSET_KEY, id);
                            GMChannel.saveGMLog(connection, player, "添加资源:" + asset.getName() + "x" + count, code,
                                    optionType + ":" + id + ":" + count);
                        } else {
                            GMChannel.sendError(connection, "参数错误!");
                            return;
                        }
                        break;
                    case CodeFactory.GM_OPTION_ADD_CARD:
                        boolean result = bagInfo.addCard(id, count);
                        if (!result) {
                            GMChannel.sendError(connection, "参数错误!");
                            return;
                        }
                        out.writeUTF(getCardStr(player));
                        out.writeUTF(getPropStr(player));
                        CardConfig card = DataFactory.getInstance().getGameObject(DataFactory.CARD_KEY, id);
                        GMChannel.saveGMLog(connection, player, "添加卡牌:" + card.getName() + "x" + count, code,
                                optionType + ":" + id + ":" + count);
                        break;
                    case CodeFactory.GM_OPTION_ADD_MONEY:
                        player.addMoney(count);
                        out.writeUTF(getAssetStr(player));
                        GMChannel.saveGMLog(connection, player, "添加资源:钻石x" + count, code, optionType + ":" + id + ":" + count);
                        break;
                    case CodeFactory.GM_OPTION_ADD_EXP:
                        if (count <= 0) {
                            GMChannel.sendError(connection, "参数错误!");
                            return;
                        }
                        int beforeLv = player.getLv();
                        TwoTuple<Boolean, Boolean> expResult = player.addExp(count);
                        out.writeUTF(getLvData(player));
                        if (expResult.getFirst()) {
                            GameServer.getInstance().getWorldManager()
                                    .updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_FC, player, player.fc);
                        }

                        if (playerController != null) {
                            player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS, ConfigFactory.ASSET_EXP_KEY,
                                    count, player.getExp());
                            if (expResult.getFirst())// 推送升级消息
                            {
                                playerController.updateFC();

                                player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER,
                                        SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_LV_VALUE, player.getLv() - beforeLv,
                                        player.getLv(), true);
                            }
                            // if(expResult.getSecond())//推送获得技能消息
                            // {
                            // SendUtils.sendRedPointRemind(playerController,
                            // SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_MASTER);
                            // }
                        }
                        GMChannel.saveGMLog(connection, player, "添加资源:玩家经验x" + count, code, optionType + ":" + id + ":" + count);
                        break;
                    case CodeFactory.GM_OPTION_JUMP_GUIDE:
                        SettingInfo settingInfo = player.getExtInfo(SettingInfo.class);
                        settingInfo.setGuideProgress(id + "");
                        break;
                }
            }
        }

        if (playerController == null) {
            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            playerService.update(player);
        } else {
            MsgUtils.addPlayerGoodsChange(SGMainProto.E_MSG_ID.MsgID_System_GMCmd_VALUE, playerController);

            SendUtils.sendChangeData(0, playerController);
        }

        connection.sendMsg(code, out.getBytes());
    }



    private static void playerClear(NettyConnection connection, ByteBuffer data, int code)
    {
        String objectIndex = data.readUTF();

        TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
                .getPlayerResult(objectIndex);
        if (playerResult.getFirst() == null) {
            GMChannel.sendError(connection, "玩家不存在");
            return;
        }

        Player player = playerResult.getFirst();

        player.lock = true;

        GameServer.getInstance().removePlayerWorldInfo(player);

        player.clearAll();

        if (playerResult.getSecond() == null) {
            GMChannel.savePlayer(player);
        } else {
            PlayerMsgChannel playerMsgChannel = SpringContext.getBean(PlayerMsgChannel.class);
            playerMsgChannel.playerBaseInfo(playerResult.getSecond());
        }

        player.lock = false;

        sendPlayerBaseInfo(connection, player, playerResult.getSecond());

        GMChannel.saveGMLog(connection, player, "清除数据", code, "clearPlayerData");
    }



    private static void rankList(NettyConnection connection, ByteBuffer data, int code) {
        int rankType = data.available() > 0 ? data.readByte() : SGCommonProto.E_RANK_TYPE.RANK_TYPE_ARENA_VALUE;

        WorldManager worldManager = GameServer.getInstance().getWorldManager();
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        int rankIndex = 0;
        if (SGCommonProto.E_RANK_TYPE.RANK_TYPE_ARENA_VALUE == rankType) {
            WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
            List<WorldArenaBean> rankList = worldArenaData.getUnderTargetRankList(ConstantFactory.RANK_COUNT);

            List<String> ids = new ArrayList<>();
            Map<String, PlayerController> onlineMap = new ConcurrentHashMap<>();
            PlayerController player = null;
            for (WorldArenaBean rank : rankList) {
                player = worldManager.getPlayerController(rank.getObjectIndex());
                if (player != null)
                    onlineMap.put(rank.getObjectIndex(), player);
                else
                    ids.add(rank.getObjectIndex());
            }

            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(ids);
            for (WorldArenaBean rankBean : rankList) {
                jsonObject = new JSONObject();
                jsonObject.put("rank", ++rankIndex);
                jsonObject.put("createTime", "0");
                jsonObject.put("lastUpdateTime", "0");
                player = onlineMap.get(rankBean.getObjectIndex());
                if (player != null) {
                    jsonObject.put("name", player.getName() + " Lv" + player.getPlayer().getLv());
                    jsonObject.put("playerIndex", player.getObjectIndex());
                    jsonObject.put("camp", player.getPlayer().camp);
                    jsonObject.put("value", player.getPlayer().fc);
                } else {
                    for (PlayerModel model : playerListByIndex) {
                        if (model.getObjectIndex().equals(rankBean.getObjectIndex())) {
                            jsonObject.put("name", model.getName() + " Lv" + model.getLevel());
                            jsonObject.put("playerIndex", model.getObjectIndex());
                            jsonObject.put("camp", model.getCamp());
                            jsonObject.put("value", model.getFc());
                            break;
                        }
                    }
                }
                jsonArray.add(jsonObject);
            }
        } else {
            List<WorldRankBean> rankBeanList = GameServer.getInstance().getWorldManager()
                    .getRankList(SGCommonProto.E_RANK_TYPE.forNumber(rankType));
            if (rankBeanList == null) {
                GMChannel.sendError(connection, "参数错误!");
                return;
            }
            rankIndex = 0;
            RankPlayerDetail rankPlayerDetail = null;
            for (WorldRankBean rankBean : rankBeanList)
            {
                jsonObject = new JSONObject();
                jsonObject.put("rank", ++rankIndex);
                jsonObject.put("playerIndex", rankBean.getObjectIndex());
                jsonObject.put("value", rankBean.getValue());
                jsonObject.put("createTime", rankBean.getCreateTime());
                jsonObject.put("lastUpdateTime", rankBean.getLastUpdateTime());

                rankPlayerDetail = worldManager.getRankPlayer(rankBean.getObjectIndex());
                jsonObject.put("name", rankPlayerDetail.getName());
                jsonObject.put("camp", rankPlayerDetail.getCamp());

                jsonArray.add(jsonObject);
            }
        }

        JSONObject response = new JSONObject();
        response.put("rankType", rankType);
        response.put("data", jsonArray.toJSONString());

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());
    }

    private static void missionCompleted(NettyConnection connection, PlayerController playerController) {
        if (playerController == null) {
            GMChannel.sendError(connection, "玩家不在线");
            return;
        }
        // 一键完成所有任务
        playerController.getPlayer().getExtInfo(TaskInfo.class).finishAllMainTask();
    }


    private static void exportAllPlayer(NettyConnection connection, ByteBuffer data, int code)
    {
        boolean online = data.readBoolean();
        int sendCount = data.readInt();

        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        if(online)
        {
            List<PlayerController> playerControllerList = GameServer.getInstance().getWorldManager().getPlayerList();
            if(playerControllerList.isEmpty())
            {
                GMChannel.sendError(connection, "没有数据");
                return;
            }
            for(PlayerController player : playerControllerList)
            {
                jsonObject = new JSONObject();
                jsonObject.put("objectIndex", player.getObjectIndex());
                jsonObject.put("name", player.getName());
                jsonObject.put("camp", player.getPlayer().camp);
                jsonObject.put("lv", player.getPlayer().getLv());
                jsonObject.put("vipLv", player.getPlayer().getVipLevel());
                jsonObject.put("fc", player.getPlayer().fc);
                jsonObject.put("money", player.getPlayer().money);
                jsonObject.put("createTime", TimeUtils.getFormatTime(player.getPlayer().getCreateTime().getTime()));
                jsonObject.put("lastLoginTime", TimeUtils.getFormatTime(player.getPlayer().getLastLoginTime().getTime()));
                jsonArray.add(jsonObject);
            }
        }
        else
        {
            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            List<PlayerModel> list = playerService.getAllPlayerList();
            if(list.isEmpty())
            {
                GMChannel.sendError(connection, "没有数据");
                return;
            }
            for(PlayerModel player : list)
            {
                jsonObject = new JSONObject();
                jsonObject.put("objectIndex", player.getObjectIndex());
                jsonObject.put("name", player.getName());
                jsonObject.put("camp", player.getCamp());
                jsonObject.put("lv", player.getLevel());
                jsonObject.put("vipLv", player.getVipLevel());
                jsonObject.put("fc", player.getFc());
                jsonObject.put("money", player.getMoney());
                jsonObject.put("createTime", TimeUtils.getFormatTime(player.getCreateTime().getTime()));
                jsonObject.put("lastLoginTime", TimeUtils.getFormatTime(player.getLastLoginTime().getTime()));
                jsonArray.add(jsonObject);
            }
        }

        JSONObject response = new JSONObject();
        response.put("data", jsonArray);

        String content = response.toJSONString();
        List<String> list = new ArrayList<>();
        int size = content.length() / sendCount;
        for(int i = 0; i < size; i++)
        {
            list.add(content.substring(i*sendCount, (i+1)*sendCount));
        }
        if(content.length()%sendCount!=0)
        {
            list.add(content.substring(size*sendCount, content.length()));
        }

        boolean isSendLength = false;
        for(String str : list)
        {
            ByteBuffer buffer = new ByteBuffer(Integer.MAX_VALUE/10);
            if(!isSendLength)
            {
                buffer.writeInt(content.length());
                isSendLength = true;
            }
            buffer.writeUTF(str);
            connection.sendMsg(code, buffer.getBytes());
        }
    }



    public static String getPropStr(Player player) {
        JSONArray jsonArray = new JSONArray();
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        List<PropDB> propList = bagInfo.getPropList();
        JSONObject jsonObject = null;
        GameObject gameObject = null;
        DataFactory dataFactory = DataFactory.getInstance();
        for (PropDB prop : propList) {
            jsonObject = new JSONObject();
            jsonObject.put("propId", prop.id);
            gameObject = dataFactory.getGameObject(DataFactory.PROP_KEY, prop.id);
            jsonObject.put("propName", gameObject.name);
            jsonObject.put("propEffect", prop.getConfig().effectValue);
            jsonObject.put("propCount", prop.count);
            jsonArray.add(jsonObject);
        }

        List<TimePropDB> timePropList = bagInfo.getTimePropData().getTimePropList();
        for (TimePropDB prop : timePropList) {
            jsonObject = new JSONObject();
            jsonObject.put("propId", prop.id);
            gameObject = dataFactory.getGameObject(DataFactory.PROP_KEY, prop.id);
            jsonObject.put("propName", gameObject.name);
            jsonObject.put("propEffect", prop.endTime);
            jsonObject.put("propCount", 1);
            jsonObject.put("propIndex", prop.uniqueId);
            jsonObject.put("propUse", prop.isUse);
            jsonArray.add(jsonObject);
        }

        return jsonArray.toJSONString();
    }

    public static String getCardStr(Player player) {
        JSONArray jsonArray = new JSONArray();
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        List<CardDB> cardList = bagInfo.getCardData().getAllCardList();
        JSONObject jsonObject = null;
        GameObject gameObject = null;
        DataFactory dataFactory = DataFactory.getInstance();
        JSONArray equipList = null;
        JSONObject equipInfo = null;
        for (CardDB cardDB : cardList) {
            jsonObject = new JSONObject();
            jsonObject.put("cardId", cardDB.id);
            gameObject = dataFactory.getGameObject(DataFactory.CARD_KEY, cardDB.id);
            jsonObject.put("cardName", gameObject.name);
            jsonObject.put("cardLv", cardDB.getLv());
            jsonObject.put("cardStar", cardDB.star);
            jsonObject.put("cardPropCount", bagInfo.getPropCount(cardDB.getConfig().lvUpProp));
            jsonObject.put("fc", cardDB.fc);
            jsonObject.put("battle", bagInfo.isBattleCard(cardDB.id));

            equipList = new JSONArray();
            for (EquipDB equipDB : cardDB.getEquipMap().values()) {
                equipInfo = new JSONObject();
                equipInfo.put("id", equipDB.id);
                equipInfo.put("name", equipDB.getConfig().name + " Lv" + equipDB.getLv());
//				equipInfo.put("lv", equipDB.getLv());
                equipInfo.put("synCount", equipDB.upCount);
                equipList.add(equipInfo);
            }

            jsonObject.put("equipInfo", equipList);

            equipList = new JSONArray();
            for (AccessoryDB accessoryDB : cardDB.getAccessoryMap().values()) {
                equipInfo = new JSONObject();
                equipInfo.put("id", accessoryDB.id);
                equipInfo.put("name", accessoryDB.getConfig().name + (accessoryDB.isActivated ? (" Lv" + accessoryDB.getLv()) : "(未激活)"));
//				equipInfo.put("lv", accessoryDB.getLv());
                equipInfo.put("upLv", accessoryDB.upLv);
                equipList.add(equipInfo);
            }

            jsonObject.put("accessoryInfo", equipList);

            jsonArray.add(jsonObject);
        }

        return jsonArray.toJSONString();
    }

    public static String getAssetStr(Player player) {
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        DataFactory dataFactory = DataFactory.getInstance();
        GameObject gameObject = null;
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        for (Map.Entry<Integer, Integer> entry : bagInfo.getAssetData().entrySet()) {
            jsonObject = new JSONObject();
            jsonObject.put("assetId", entry.getKey());
            gameObject = dataFactory.getGameObject(DataFactory.ASSET_KEY, entry.getKey());
            jsonObject.put("assetName", gameObject.name);
            jsonObject.put("assetCount", entry.getValue());
            jsonArray.add(jsonObject);
        }

        return jsonArray.toJSONString();
    }

    public static String getChannel(Object player) {
        String account = null;
        if (player instanceof Player) {
            account = ((Player) player).getAccount();
        } else if (player instanceof PlayerModel) {
            account = ((PlayerModel) player).getAccount();
        } else if (player instanceof PlayerController) {
            account = ((PlayerController) player).getPlayer().getAccount();
        }
        if (StringUtils.isNullOrEmpty(account))
            return "";

        return account.indexOf("_") == -1 ? account : account.substring(0, account.indexOf("_"));
    }

    private static String getLvData(Player player) {
        PlayerLvConfig playerLv = DataFactory.getInstance().getGameObject(DataFactory.PLAYER_LV_KEY, player.getLv());
        PlayerLvConfig nextLv = DataFactory.getInstance().getGameObject(DataFactory.PLAYER_LV_KEY, player.getLv() + 1);
        return player.getLv() + "(" + (player.getExp() - playerLv.totalExp) + "/"
                + (nextLv != null ? nextLv.exp : playerLv.exp) + ")";
    }

    private static String getVipLvData(Player player) {
        VipConfig vipConfig = DataFactory.getInstance().getGameObject(DataFactory.VIP_KEY, player.getVipLevel());
        VipConfig nextVip = DataFactory.getInstance().getGameObject(DataFactory.VIP_KEY, player.getVipLevel() + 1);
        return player.getVipLevel() + "(" + (player.getVipExp() - vipConfig.needRecharge) + "/"
                + (nextVip != null ? nextVip.needRecharge - vipConfig.needRecharge : vipConfig.needRecharge) + ")";
    }



    private static int getCardAttributeValue(CardDB cardDB, E_Attribute attribute, E_AttributePlusType type)
    {
        if(type == E_AttributePlusType.BASE)
            return Integer.parseInt(cardDB.getConfig().getSoldier().getVariable(attribute.getMsg()));
        else if(type == E_AttributePlusType.LEVEL)
            return cardDB.getConfig().getSoldier().getLevelPlus(attribute.getCode(), cardDB.getLv());
        else if(type == E_AttributePlusType.STAR)
            return cardDB.getConfig().getSoldier().getStarAttribute(attribute.getCode(), cardDB.star);
        else if(type == E_AttributePlusType.FATE)
            return cardDB.getFatePlus(attribute.getCode());
        else if(type == E_AttributePlusType.EQUIP)
            return cardDB.getEquipPlus(attribute.getCode());
        else if(type == E_AttributePlusType.ACCESSORY)
            return cardDB.getAccessoryPlus(attribute.getCode());
        else if(type == E_AttributePlusType.LIQUID)
            return cardDB.getLiquidPlus(attribute.getCode());
        else if(type == E_AttributePlusType.CHAIN)
            return cardDB.getChainPlus(attribute.getCode());
        else
            return 0;
    }

    private static JSONObject getCardAttribute(CardDB cardDB, E_AttributePlusType type, String hpGrow, String atkGrow, String defGrow, JSONObject totalAttr)
    {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", type.getCode());
        jsonObject.put("name", type.getMsg());
        jsonObject.put(E_Attribute.HP_GROW.getMsg(), hpGrow);
        jsonObject.put(E_Attribute.ATK_GROW.getMsg(), atkGrow);
        jsonObject.put(E_Attribute.DEF_GROW.getMsg(), defGrow);
        int hp, atk, def, cri, rec, add, exd, hit, eva;
        jsonObject.put(E_Attribute.HP.getMsg(), hp = getCardAttributeValue(cardDB, E_Attribute.HP, type));
        jsonObject.put(E_Attribute.ATK.getMsg(), atk = getCardAttributeValue(cardDB, E_Attribute.ATK, type));
        jsonObject.put(E_Attribute.DEF.getMsg(), def = getCardAttributeValue(cardDB, E_Attribute.DEF, type));
        jsonObject.put(E_Attribute.CRI.getMsg(), cri = getCardAttributeValue(cardDB, E_Attribute.CRI, type));
        jsonObject.put(E_Attribute.REC.getMsg(), rec = getCardAttributeValue(cardDB, E_Attribute.REC, type));
        jsonObject.put(E_Attribute.ADD.getMsg(), add = getCardAttributeValue(cardDB, E_Attribute.ADD, type));
        jsonObject.put(E_Attribute.EXD.getMsg(), exd = getCardAttributeValue(cardDB, E_Attribute.EXD, type));
        jsonObject.put(E_Attribute.HIT.getMsg(), hit = getCardAttributeValue(cardDB, E_Attribute.HIT, type));
        jsonObject.put(E_Attribute.EVA.getMsg(), eva = getCardAttributeValue(cardDB, E_Attribute.EVA, type));

        if(!totalAttr.containsKey("id"))
        {
            totalAttr.put("id", E_AttributePlusType.ALL.getCode());
            totalAttr.put("name", E_AttributePlusType.ALL.getMsg());
            totalAttr.put(E_Attribute.HP_GROW.getMsg(), hpGrow);
            totalAttr.put(E_Attribute.ATK_GROW.getMsg(), atkGrow);
            totalAttr.put(E_Attribute.DEF_GROW.getMsg(), defGrow);
            totalAttr.put(E_Attribute.HP.getMsg(), hp);
            totalAttr.put(E_Attribute.ATK.getMsg(), atk);
            totalAttr.put(E_Attribute.DEF.getMsg(), def);
            totalAttr.put(E_Attribute.CRI.getMsg(), cri);
            totalAttr.put(E_Attribute.REC.getMsg(), rec);
            totalAttr.put(E_Attribute.ADD.getMsg(), add);
            totalAttr.put(E_Attribute.EXD.getMsg(), exd);
            totalAttr.put(E_Attribute.HIT.getMsg(), hit);
            totalAttr.put(E_Attribute.EVA.getMsg(), eva);
        }
        else
        {
            totalAttr.put(E_Attribute.HP.getMsg(), totalAttr.getIntValue(E_Attribute.HP.getMsg()) + hp);
            totalAttr.put(E_Attribute.ATK.getMsg(), totalAttr.getIntValue(E_Attribute.ATK.getMsg()) + atk);
            totalAttr.put(E_Attribute.DEF.getMsg(), totalAttr.getIntValue(E_Attribute.DEF.getMsg()) + def);
            totalAttr.put(E_Attribute.CRI.getMsg(), totalAttr.getIntValue(E_Attribute.CRI.getMsg()) + cri);
            totalAttr.put(E_Attribute.REC.getMsg(), totalAttr.getIntValue(E_Attribute.REC.getMsg()) + rec);
            totalAttr.put(E_Attribute.ADD.getMsg(), totalAttr.getIntValue(E_Attribute.ADD.getMsg()) + add);
            totalAttr.put(E_Attribute.EXD.getMsg(), totalAttr.getIntValue(E_Attribute.EXD.getMsg()) + exd);
            totalAttr.put(E_Attribute.HIT.getMsg(), totalAttr.getIntValue(E_Attribute.HIT.getMsg()) + hit);
            totalAttr.put(E_Attribute.EVA.getMsg(), totalAttr.getIntValue(E_Attribute.EVA.getMsg()) + eva);
        }

        return jsonObject;
    }
}
